package cn.iocoder.yudao.module.product.sku.api;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.product.sku.ProductSkuApi;
import cn.iocoder.yudao.module.api.product.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.api.product.sku.dto.ProductSkuUpdateStockOrSalesCountReqDTO;
import cn.iocoder.yudao.module.product.sku.convert.ProductSkuConvert;
import cn.iocoder.yudao.module.product.sku.dal.dataobject.ProductSkuDO;
import cn.iocoder.yudao.module.product.sku.service.ProductSkuService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.module.api.product.ErrorCodeConstants.SKU_NOT_EXISTS;
import static cn.iocoder.yudao.module.api.product.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH;

/**
 * 产品 SKU API 实现类
 *
 * @author LeeYan9
 * @since 2022-09-06
 */
@Service
@Validated
public class ProductSkuApiImpl implements ProductSkuApi {

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private ProductSkuService productSkuService;

    @Override
    public ProductSkuRespDTO getSku(Long id) {
        ProductSkuDO sku = productSkuService.getSku(id);
        return BeanUtils.toBean(sku, ProductSkuRespDTO.class);
    }

    @Override
    public ProductSkuRespDTO validateSku(Long id) {
        ProductSkuRespDTO sku = getSku(id);
        if (sku == null) {
            throw exception(SKU_NOT_EXISTS);
        }
        return sku;
    }

    @Override
    public ProductSkuRespDTO validateSku(Long id, Integer count) {
        ProductSkuRespDTO sku = validateSku(id);
        if (count > sku.getStock()) {
            throw exception(SKU_STOCK_NOT_ENOUGH);
        }
        return sku;
    }

    @Override
    public List<ProductSkuRespDTO> getSkuList(Collection<Long> ids) {
        List<ProductSkuDO> skus = productSkuService.getSkuList(ids);
        return ProductSkuConvert.INSTANCE.convert(skus);
    }

    @Override
    public List<ProductSkuRespDTO> validateSkus(Map<Long, Integer> skuIdCountMap) {
        List<ProductSkuRespDTO> skus = getSkuList(skuIdCountMap.keySet());
        // 校验产品 SKU
        skus.forEach(sku -> {
            Integer count = skuIdCountMap.get(sku.getId());
            if (count == null) {
                throw exception(SKU_NOT_EXISTS);
            }
            if (count > sku.getStock()) {
                throw exception(SKU_STOCK_NOT_ENOUGH);
            }
        });
        return skus;
    }

    @Override
    public List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds) {
        List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIds(spuIds);
        return BeanUtils.toBean(skus, ProductSkuRespDTO.class);
    }

    @Override
    public List<ProductSkuRespDTO> validateSkus(List<Long> spuIds, Collection<Long> skuIds) {
        List<ProductSkuRespDTO> skus = getSkuListBySpuId(spuIds);
        Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId);
        skuIds.forEach(skuId -> {
            if (!skuMap.containsKey(skuId)) {
                throw exception(SKU_NOT_EXISTS);
            }
        });
        return skus;
    }

    @Override
    public void updateSkuStock(ProductSkuUpdateStockOrSalesCountReqDTO stockReqDTO) {
        productSkuService.updateSkuStock(stockReqDTO);
    }

    @Override
    public void updateSkuSalesCount(ProductSkuUpdateStockOrSalesCountReqDTO stockReqDTO) {
        productSkuService.updateSkuSalesCount(stockReqDTO);
    }

}
